/***************************************************************************
 *   Copyleft 2008-2009 by												   *
 *	 Iwanicki Krzysztof													   *
 *   <gamma.mini.pw.edu.pl/~iwanickik>									   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 ***************************************************************************/
#include "./vResourcesLoader.h"
#include "../../Macros/vLogMacros.h"

namespace Vendetta {
	vResourcesLoader::vResourcesLoader(const vString& fileName) {
		try {
			loadFile(fileName);	
		} catch (vFatalException& e) {
			throw vFatalException("Loading resources failure due to: %s In vResourcesLoader::Ctor.", e.ErrorMsg().ToConstCharPtr());
		}
	}

	vResourcesLoader::~vResourcesLoader() {
		for (vUInt uiPos = 0; uiPos < mResources.Size(); ++uiPos) {
			vPair<vString, ResList> pair = mResources.Element(uiPos);
			pair.Second.Clear();
		}
		mResources.Clear();
	}

	vResourcesLoader::vResourcesLoader(const vResourcesLoader& loader) {
		mResources = loader.mResources;
		mFileName = loader.mFileName;
	}

	vResourcesLoader& vResourcesLoader::operator=(const vResourcesLoader& loader) {
		if (this != &loader) {
			mResources = loader.mResources;
			mFileName = loader.mFileName;
		}

		return *this;
	}

	vResourcesLoader::ResList vResourcesLoader::ResourceGroup(const vString& groupName) {
		vResourcesLoader::ResList list;

		if (mResources.Contains(groupName)) {
			return mResources[groupName];
		}

		return list;
	}

	vVoid vResourcesLoader::loadFile(const vString& fileName) {
		TiXmlDocument doc(fileName.ToConstCharPtr());//"res/resources.vrs"

		if (!doc.LoadFile()) {
			throw vFatalException("Can't load file: \"res/resources.vrs\". In vResourcesLoader::loadFile.");
		}

		TiXmlHandle hDoc(&doc);
		TiXmlElement* pElem = vNull;
		TiXmlHandle hRoot(0);

		pElem = hDoc.FirstChildElement().Element();
		if (!pElem || strcmp(pElem->Value(), "resources") != 0) {
			throw vFatalException("Can't find \"resources\" node. In vResourcesLoader::loadFile.");
		}
		hRoot = TiXmlHandle(pElem);
		pElem = hRoot.FirstChild().Element();

		while (pElem) {
			const vChar* tagName = pElem->Value();
			if (!strcmp(tagName, "textures")) {
				mResources<<vPair<vString, ResList>("Textures", loadTextures(pElem));
			} 
			pElem = pElem->NextSiblingElement();
		}
	}

	vResourcesLoader::ResList vResourcesLoader::loadTextures(TiXmlElement *pElem) {
		TiXmlElement* pChildElem = vNull;
		TiXmlNode* pChild = vNull;
		ResList list;
		vString dir = "";

		if (pElem) {
			dir = pElem->Attribute("dir");
			while ((pChild = pElem->IterateChildren(pChild))) {
				if ((pChildElem = pChild->ToElement())) {
					if (!strcmp(pChildElem->Value(), "texture2d")) {
						list.AddAsLast(loadTexture2d(pChildElem, dir));
					} 
				}
			}
		} 

		return list;
	}

	vResourcesLoader::vEntryPair vResourcesLoader::loadTexture2d(TiXmlElement *pElem, const vString& dir) {
		vEntryPair entry;

		if (pElem) {
			entry.mFileName = dir + pElem->Attribute("fileName");
			entry.mResourceName = pElem->Attribute("name");
		}

		return entry;
	}

	vVoid vResourcesLoader::Print() {
		for (vUInt uiPos = 0; uiPos < mResources.Size(); ++uiPos) {
			vPair<vString, ResList> pair = mResources.Element(uiPos);
			LOGS_DEBUG("[%s]", pair.First.ToConstCharPtr());
			for (vUInt uiPos2 = 0; uiPos2 < pair.Second.Size(); uiPos2++) {
				LOGS_DEBUG("%s = %s", pair.Second[uiPos2].mFileName.ToConstCharPtr(), 
					pair.Second[uiPos2].mResourceName.ToConstCharPtr());
			}
		}
	}
}